package bibliOnline.db;

import java.sql.*;

import bibliOnline.util.ResponseMessage;
import bibliOnline.util.details.UserDetails;
import java.util.ArrayList;

/**
 * Gestisce le operazioni di accesso al database relative agli utenti. 
 * 
 * @author Fabio Righi
 */
public class UserManager 
{
    /**
     * Inserisce un nuovo utente nel database 
     * 
     * @param user_data oggetto contenente i dati che verranno inseriti nel database
     * @param tipo_utente il tipo di utente da inserire. true se è un utente privilegiato (bibliotecario)
     * 
     * @see UserDetails
     */
    public static ResponseMessage insert(UserDetails user_data,boolean tipo_utente)  
    {
        PreparedStatement statement;
        String sql;
        ResponseMessage risposta= new ResponseMessage(false,"",false);

        try {
            if(tipo_utente==false)
                sql = "INSERT INTO CUSTOMER (USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ADDRESS, EMAIL) VALUES (?,?,?,?,?,?)";
            else
                sql = "INSERT INTO LIBRARIAN (USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ADDRESS) VALUES (?,?,?,?,?)";
            
            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data.getUsername());
            statement.setString(2, user_data.getPassword());
            statement.setString(3, user_data.getFirstname());
            statement.setString(4, user_data.getLastname());
            statement.setString(5, user_data.getAddress());
            if(tipo_utente==false)
                statement.setString(6, user_data.getEmail());

            statement.executeUpdate();
            statement.close();
            
            risposta.setMessage(DBConnection.getProperty("MESSAGE_REGISTRATION_OK"));
            risposta.setSuccess(true);
            
        } catch (Exception ex) {
            risposta.setMessage(DBConnection.getProperty("MESSAGE_DB_ERROR"));
            risposta.setSuccess(false);
        }    
	
        return risposta;
    }
    
    /**
     * Controlla se i dati di login sono corretti (ovvero hanno corrispondenza esatta nel database) 
     * 
     * @param user_data_check oggetto contenente i dati dell'utente che si vuole controllare
     * @return se l'utente è stato trovato ritorna i suoi dati, altrimenti ritorna null
     * 
     * @see UserDetails
     */
    public static UserDetails login(UserDetails user_data_check)  
    {
        PreparedStatement statement;
        ResultSet result;
        String sql;
        boolean exists=false;
        UserDetails user_data = new UserDetails();      
        String password_codificata = new String();
        
        System.out.println(password_codificata);
        

        try {
            sql = "SELECT USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ADDRESS, EMAIL FROM CUSTOMER WHERE USERNAME = ?";

            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data_check.getUsername());

            result = statement.executeQuery();

            if (result.next()) 
            {
                if (result.getString("PASSWORD").equals(user_data_check.getPassword())) 
                {
                    exists = true;

                    user_data.setType(UserDetails.CUSTOMER);
                    user_data.setEmail(result.getString("EMAIL"));
                    user_data.setUsername(result.getString("USERNAME"));
                    user_data.setPassword(result.getString("PASSWORD"));
                    user_data.setFirstname(result.getString("FIRSTNAME"));
                    user_data.setLastname(result.getString("LASTNAME"));
                    user_data.setAddress(result.getString("ADDRESS"));
                }
            }

            statement.close();

            if (exists) 
                return user_data;

            sql = "SELECT USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ADDRESS FROM LIBRARIAN WHERE USERNAME = ?";

            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data_check.getUsername());

            result = statement.executeQuery();

            if (result.next()) 
            {
                if (result.getString("PASSWORD").equals(user_data_check.getPassword())) 
                {
                    exists = true;

                    user_data.setType(UserDetails.LIBRARIAN);
                    user_data.setUsername(result.getString("USERNAME"));
                    user_data.setPassword(result.getString("PASSWORD"));
                    user_data.setFirstname(result.getString("FIRSTNAME"));
                    user_data.setLastname(result.getString("LASTNAME"));
                    user_data.setAddress(result.getString("ADDRESS"));
                }
            }

            statement.close();

            if (exists) 
                return user_data;
            else 
                return null;
            
        } catch (Exception ex) {
            return null; 
        }
    }
    
    
    /**
     * Controlla se un utente esiste (ovvero è presente nel database un record con un determinato username) 
     * 
     * @param user_data_check oggetto contenente i dati dell'utente di cui si vuole controllare l'esistenza
     * @return true se l'utente è stato trovato, false altrimenti.
     * 
     * @see UserDetails
     */    
    public static boolean exists(UserDetails user_data_check) 
    {
        PreparedStatement statement;
        ResultSet result;
        String sql;
        boolean exists=true;

        try 
        {
            if (user_data_check.getType().equals(UserDetails.CUSTOMER)) 
                sql = "SELECT USERNAME FROM CUSTOMER WHERE USERNAME = ?";
            else 
                sql = "SELECT USERNAME FROM LIBRARIAN WHERE USERNAME = ?";

            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data_check.getUsername());

            result = statement.executeQuery();

            if (result.next()) 
                exists = false;
            else 
                exists = true;

            statement.close();
        } catch (Exception ex) {
           
        }

        return exists;
    }
    
    
    /**
     * Rimuove un utente dal database.
     * 
     * @param user_data_remove oggetto contenente i dati dell'utente che si vuole eliminare dal database.
     * Perchè la rimozione abbia successo è specificare anche la password.
     * @return messaggio di stato relativo alla cancellazione
     * 
     * @see UserDetails
     */
    public static ResponseMessage remove(UserDetails user_data_remove)  
    {
        PreparedStatement statement;
        ResultSet result;
        String sql;
        ResponseMessage risposta= new ResponseMessage(false,"",false);
        boolean exists=false;  

        try {
            sql = "SELECT USERNAME, PASSWORD FROM CUSTOMER WHERE USERNAME = ?";

            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data_remove.getUsername());

            result = statement.executeQuery();
            
            if (result.next()) 
            {
                if (result.getString("PASSWORD").equals(user_data_remove.getPassword())) 
                    exists=true;
                else 
                    risposta.setMessage(DBConnection.getProperty("MESSAGE_DELETE_NO_PSW"));    
            } 
            else 
                risposta.setMessage(DBConnection.getProperty("MESSAGE_DELETE_NO_USER"));
            
            statement.close();
            
            if(!exists)
                return risposta;
                
            sql = "DELETE FROM CUSTOMER WHERE USERNAME = ? AND PASSWORD = ?";

            statement = DBConnection.prepareStatement(sql);

            statement.setString(1, user_data_remove.getUsername());
            statement.setString(2, user_data_remove.getPassword());
            
            statement.executeUpdate();
            statement.close();
            
            risposta.setMessage(DBConnection.getProperty("MESSAGE_DELETE_OK"));
            risposta.setSuccess(true);

        } catch (Exception ex) {
            risposta.setMessage(DBConnection.getProperty("MESSAGE_DB_ERROR"));
            risposta.setSuccess(false);
        }
        
        return risposta;
    }
    
    /**
     * Funzione che richiede la ista degli utenti della biblioteca
     * 
     * @param user Utente che ha richiesto l'elenco
     * @return Lista degli utenti
     * @throws Exception Occorre essere bibliotecari
     */
    public static ArrayList<UserDetails> getUserList(UserDetails user) throws Exception {
        
        //Controllo se l'utente è bibliotecario
        if (!user.getType().equals("LIBRARIAN")) {
            throw new Exception("Per poter visualizzare la lista utenti occorre essere bibliotecari!");
        }

        System.out.println("Il bibliotecario " + user.getUsername() + " richiede la lista degli utenti");
        
        ArrayList<UserDetails> users = new ArrayList<UserDetails>();
        String sql = "select username from customer";
        
        PreparedStatement statement = DBConnection.prepareStatement(sql);
        ResultSet rs = statement.executeQuery();
        
        while (rs.next()) {
            UserDetails current_user = new UserDetails();
            current_user.setUsername(rs.getString("username"));
            users.add(current_user);
        }
        
        rs.close();
        statement.close();
        
        return users;
    }
    
}
